/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.commons.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

//图片处理工具类
public class ImageUtils {

    //图片旋转
    public static byte[] imageRotate(byte[] imageContent, String format, int angle) throws IOException {

        BufferedImage image = byteToImage(imageContent);

        int src_width = image.getWidth(null);
        int src_height = image.getHeight(null);
        // 计算旋转后图片的尺寸
        Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
                src_width, src_height)), angle);
        BufferedImage result = null;
        result = new BufferedImage(rect_des.width, rect_des.height,
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = null;
        try{
            graphics = result.createGraphics();
            // 进行转换
            graphics.translate((rect_des.width - src_width) / 2,
                    (rect_des.height - src_height) / 2);
            graphics.rotate(Math.toRadians(angle), src_width / 2, src_height / 2);

            graphics.drawImage(image, null, null);
        }finally {
            if(graphics!=null){
                graphics.dispose();
            }
        }

        return imageToByte(result, format);
    }

    //图片缩放
    public static byte[] imageZoom(byte[] imageContent, String format, int width, int height) throws IOException {

        BufferedImage image = byteToImage(imageContent);

        //新建一个和Image对象相同大小的画布
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        //获取缩放后的Image对象
        Image _img = image.getScaledInstance(width, height, Image.SCALE_DEFAULT);

        //获取画笔
        Graphics2D graphics = null;
        try{
            graphics = newImage.createGraphics();
            //将Image对象画在画布上,最后一个参数,ImageObserver:接收有关 Image 信息通知的异步更新接口,没用到直接传空
            graphics.drawImage(_img, 0, 0, null);
        }finally {
            //释放资源
            graphics.dispose();
        }
        return imageToByte(newImage, format);
    }

    private static BufferedImage byteToImage(byte[] image) throws IOException {
        ByteArrayInputStream in = null;
        try {
            in = new ByteArrayInputStream(image);    //将b作为输入流；
            return ImageIO.read(in);
        }finally {
            if(in!=null){
                in.close();
            }
        }
    }

    private static byte[] imageToByte(BufferedImage image, String format) throws IOException {
        if (format.equalsIgnoreCase("jpg") || format.equalsIgnoreCase("jpeg")) {
            //重画一下，要么会变色
            BufferedImage tag;
            tag = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();

            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
            g.dispose();
            image = tag;
        }

        ByteArrayOutputStream out = null;
        try{
            out = new ByteArrayOutputStream();
            boolean flag = ImageIO.write(image, format, out);
            return out.toByteArray();
        }finally {
            if(out!=null){
                out.close();
            }
        }
    }

    ///计算图片旋转
    private static Rectangle CalcRotatedSize(Rectangle src, int angle) {
        // 如果旋转的角度大于90度做相应的转换
        if (angle < 0)
            angle = 360 - angle;
        angle = angle % 360;
        if (angle >= 90) {
            if (angle / 90 % 2 == 1) {
                int temp = src.height;
                src.height = src.width;
                src.width = temp;
            }
            angle = angle % 90;
        }

        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
        double len = 2 * Math.sin(Math.toRadians(angle) / 2) * r;
        double angle_alpha = (Math.PI - Math.toRadians(angle)) / 2;
        double angle_width = Math.atan((double) src.height / src.width);
        double angle_height = Math.atan((double) src.width / src.height);

        int len_width = (int) (len * Math.cos(Math.PI - angle_alpha
                - angle_width));
        int len_height = (int) (len * Math.cos(Math.PI - angle_alpha
                - angle_height));
        int des_width = src.width + len_width * 2;
        int des_height = src.height + len_height * 2;
        return new Rectangle(new Dimension(des_width, des_height));
    }
}
